package cn.chiship.framework.common.quartz;

import cn.chiship.framework.common.annotation.JobAnnotation;
import cn.chiship.sdk.framework.util.SpringContextUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @author lijian
 */
public class SchedulingRunnable implements Runnable {

	private static final Logger LOGGER = LoggerFactory.getLogger(SchedulingRunnable.class);

	private String beanName;

	private String methodName;

	private String params;

	public SchedulingRunnable(String beanName, String methodName) {
		this(beanName, methodName, null);
	}

	public SchedulingRunnable(String beanName, String methodName, String params) {
		this.beanName = beanName;
		this.methodName = methodName;
		this.params = params;
	}

	@Override
	public void run() {
		try {
			Object target = SpringContextUtil.getBean(beanName);
			Method method = null;
			if (StringUtils.isNotEmpty(params)) {
				method = target.getClass().getDeclaredMethod(methodName, String.class);
			}
			else {
				method = target.getClass().getDeclaredMethod(methodName);
			}

			/*
			 * JobAnnotation jobAnnotation=method.getAnnotation(JobAnnotation.class);
			 * Field[] fields=jobAnnotation.getClass().getDeclaredFields(); for (Field
			 * field : fields) { }
			 */

			ReflectionUtils.makeAccessible(method);
			if (StringUtils.isNotEmpty(params)) {
				method.invoke(target, params);
			}
			else {
				method.invoke(target);
			}
		}
		catch (Exception ex) {
			CronTaskRegistrar cronTaskRegistrar = SpringContextUtil.getBean(CronTaskRegistrar.class);
			SchedulingRunnable task = new SchedulingRunnable(this.beanName, this.methodName, this.params);
			cronTaskRegistrar.removeCronTask(task);
			LOGGER.error(String.format("定时任务执行异常 - bean：%s，方法：%s，参数：%s ", beanName, methodName, params), ex);
		}

	}

	@Override
	public boolean equals(Object o) {
		if (this == o) {
			return true;
		}
		if (o == null || getClass() != o.getClass()) {
			return false;
		}
		SchedulingRunnable that = (SchedulingRunnable) o;
		if (params == null) {
			return beanName.equals(that.beanName) && methodName.equals(that.methodName) && that.params == null;
		}

		return beanName.equals(that.beanName) && methodName.equals(that.methodName) && params.equals(that.params);
	}

	@Override
	public int hashCode() {
		if (params == null) {
			return Objects.hash(beanName, methodName);
		}

		return Objects.hash(beanName, methodName, params);
	}

}